import { reactive, ref, Ref, toRefs } from "vue";
import { usePagination } from "./pagination";
import { useColumns } from "./columns";
import { ZTableProps } from "../ZTable.vue";
import { ZTableMethods } from "../typings";
import { DataTableSortState } from "naive-ui";

export const emptyDataSourceApi = () => Promise.resolve([]);

export function useTableCore(
  props: Required<ZTableProps>,
  searchFormRef: Ref<any>
) {
  async function fetchDataSource() {
    if (props.dataSourceApi == emptyDataSourceApi) return;
    nTableProps.data = [];
    nTableProps.loading = true;

    const searchParams = searchFormRef.value.getFieldsValue();
    if (pagination && nTableProps.remote) {
      Object.assign(searchParams, props.getSorterParams(sorterRef.value));
      searchParams[props.pageField] = pagination.page;
      searchParams[props.limitField] = pagination.pageSize;
      const dataSource: any = await props
        .dataSourceApi(searchParams)
        .finally(() => {
          nTableProps.loading = false;
        });
      pagination.pageCount = Math.ceil(
        dataSource[props.totalField] / (pagination.pageSize ?? 1)
      );
      pagination.itemCount = dataSource[props.totalField];
      nTableProps.data = dataSource[props.listField] as any[];
    } else {
      const dataSource: any = await props
        .dataSourceApi(searchParams)
        .finally(() => {
          nTableProps.loading = false;
        });
      nTableProps.data = dataSource;
    }
  }

  // refetch with current search params, but redirect to page 1.
  async function reload() {
    if (pagination) {
      pagination.page = 1;
    }
    await fetchDataSource();
  }

  const tableMethods: ZTableMethods = {
    fetchDataSource,
    reload,
  };

  /* pagination */
  const pagination = usePagination(props.tableProps.pagination, tableMethods);
  /* columns */
  const columns = useColumns(props, pagination, tableMethods);
  /* sorter: only ONE field is supported to sort by it */
  const sorterRef: any = ref({});
  /* tableProps */
  const nTableProps: any = reactive({
    onUpdateSorter: async ({ order, columnKey }: DataTableSortState) => {
      sorterRef.value = order ? { [columnKey]: order } : {};
      await fetchDataSource();
    },
    ...toRefs(props.tableProps),
    pagination,
    columns,
  });

  return { nTableProps, tableMethods };
}
